<template>
  <div class="app-container">
    <el-row :gutter="20">
      <el-col :span="7">
        <el-card class="box-card">
          <el-form :inline="true">
            <!-- <el-select
              v-model="listQuery.domainId"
              placeholder="请选择系统域"
              style="width:150px;"
              @change="domainSelectChange"
            >
              <el-option
                v-for="item in domainList"
                :key="item.value"
                :value="item.value"
                :label="item.label"
              />
            </el-select> -->
            <el-form-item>
              <el-button
                class="filter-item"
                type="primary"
                icon="el-icon-refresh"
                @click="handleFilter"
              />
              <el-button
                class="filter-item"
                style="margin-left: 10px;"
                type="primary"
                icon="el-icon-edit"
                @click="handleCreate"
              >
                新增目录菜单
              </el-button>
            </el-form-item>
          </el-form>

          <div class="h-[calc(100vh-245px)]">
            <el-scrollbar class="!h-[100%]">
              <el-tree
                class="menu-tree"
                ref="tree"
                :data="treeData"
                :props="defaultProps"
                node-key="id"
                :expand-on-click-node="false"
                :default-expanded-keys="expandedKeys"
                highlight-current
                border
                style="height: 100%;"
                @node-click="handleNodeClick"
                @node-expand="handleNodeExpand"
                @node-collapse="handleNodeCollapse"
              >
                <span slot-scope="{ node, data }" class="custom-tree-node">
                  <span>
                    {{ data.title }}
                    <!-- <span style="font-size:12px;">
                    （{{ data.type | typeAnalysis }}）
                  </span> -->
                  </span>
                  <span>
                    <el-button
                      type="text"
                      size="mini"
                      @click="handleEdit(data)"
                    >
                      修改
                    </el-button>
                    <popover-confirm
                      text="删除"
                      button-type="text"
                      button-size="mini"
                      @click="handleDelete(data)"
                    >
                      确定删除吗?
                    </popover-confirm>
                  </span>
                </span>
              </el-tree>
            </el-scrollbar>
          </div>
        </el-card>
      </el-col>
      <el-col :span="17">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <el-button
              class="filter-item"
              style="margin-left: 10px;"
              type="primary"
              icon="el-icon-edit"
              @click="slaveHandleCreate"
            >
              新增功能按钮
            </el-button>
            <el-button
              class="filter-item"
              style="margin-left: 10px;"
              type="primary"
              icon="el-icon-edit"
              @click="slaveHandleCrud"
            >
              新增CRUD
            </el-button>
            <el-button
              class="filter-item"
              style="margin-left: 10px;"
              type="primary"
              icon="el-icon-edit"
              @click="batchHandle"
            >
              批量新增功能按钮
            </el-button>
          </div>
          <el-table class="tree-node" :data="slaveTableData" border fit stripe>
            <el-table-column prop="name" label="名称" width="150" />
            <el-table-column prop="type" label="类型" width="100">
              <template slot-scope="{ row }">
                {{ row.type | typeAnalysis }}
              </template>
            </el-table-column>
            <el-table-column
              prop="sort"
              label="排序值"
              align="center"
              width="100"
            />
            <el-table-column
              prop="display"
              label="是否显示"
              align="center"
              width="100"
            />
            <el-table-column
              prop="status"
              label="状态"
              align="center"
              width="100"
            />
            <el-table-column prop="perm" label="权限" width="250" />
            <el-table-column prop="path" label="路径" />
            <el-table-column
              fixed="right"
              align="center"
              header-align="center"
              label="操作"
              width="200"
            >
              <template slot-scope="scope">
                <el-button
                  size="mini"
                  type="primary"
                  @click="slaveHandleEdit(scope.row)"
                >
                  编辑
                </el-button>
                <popover-confirm
                  text="删除"
                  @click="slaveHandleDelete(scope.row)"
                >
                  确定删除吗?
                </popover-confirm>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>
    <el-dialog
      :visible.sync="dialogFormVisible"
      :modal="false"
      :close-on-click-modal="false"
      :title="postForm.resourceId ? '修改' : '增加'"
      width="40%"
      class="mini-el-dialog"
    >
      <el-form
        ref="form"
        :rules="rules"
        :model="postForm"
        label-position="left"
        class="resourceForm"
        label-width="100px"
      >
        <el-form-item label="所属系统域" prop="domainId">
          <el-select v-model="postForm.domainId" placeholder="请选择系统域">
            <el-option
              v-for="item in domainList"
              :key="item.value"
              :value="item.value"
              :label="item.label"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          label="上级"
          prop="parentId"
          v-if="cascaderOptions && cascaderOptions.length > 0"
        >
          <el-cascader
            v-model="parentArr"
            :options="cascaderOptions"
            :props="cascaderProps"
            change-on-select
            clearable
            placeholder="请选择"
            @change="parentSelectChange"
          />
        </el-form-item>
        <el-form-item label="资源名称" prop="name">
          <el-input v-model="postForm.name" />
        </el-form-item>
        <el-form-item label="资源类型" prop="type">
          <el-select v-model="postForm.type" placeholder="请选择">
            <el-option label="目录" value="0" />
            <el-option label="菜单" value="1" />
            <el-option label="功能/按钮" value="2" />
          </el-select>
        </el-form-item>
        <el-form-item label="图标" prop="icon">
          <el-input v-model="postForm.icon" />
        </el-form-item>
        <el-form-item label="权限资源" prop="perm">
          <el-input
            v-for="(tag, index) in dynamicTags"
            :key="'tag_' + index"
            v-model="dynamicTags[index]"
            size="small"
            clearable
            @clear="removeTag(index)"
          />
          <el-input
            v-if="inputVisible"
            ref="saveTagInput"
            v-model="inputValue"
            class="input-new-tag"
            size="small"
            @keyup.enter.native="handleInputConfirm"
            @blur="handleInputConfirm"
          />
          <el-button
            :disabled="inputVisible"
            class="button-new-tag"
            size="small"
            @click="showInput"
          >
            添加
          </el-button>
        </el-form-item>
        <el-form-item label="前端路由" prop="path">
          <el-input v-model="postForm.path" />
        </el-form-item>
        <el-form-item label="排序值" prop="sort">
          <el-input-number
            v-model="postForm.sort"
            :step="1"
            :min="1"
            controls-position="right"
          />
        </el-form-item>
        <el-form-item label="是否显示" prop="display">
          <el-radio-group v-model="postForm.display">
            <el-radio :label="1">是</el-radio>
            <el-radio :label="0">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="postForm.status">
            <el-radio :label="1">正常</el-radio>
            <el-radio :label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="postForm.remark" type="textarea" />
        </el-form-item>
        <el-form-item label="自定义配置" prop="remark">
          <configure v-model="postForm.configure" v-if="dialogFormVisible" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm">确定</el-button>
      </div>
    </el-dialog>
    <el-dialog
      :visible.sync="crudFormVisible"
      :modal="false"
      :close-on-click-modal="false"
      title=""
      width="40%"
      class="mini-el-dialog"
    >
      <el-form
        ref="crudForm"
        :model="crudForm"
        label-position="left"
        class="resourceForm"
        label-width="100px"
      >
        <el-form-item label="接口前缀" prop="crudPrefixPath">
          <el-input
            v-model="crudPrefixPath"
            placeholder="请输入权限地址前缀（非必填），如：/yyt/sys/user"
          />
        </el-form-item>
        <el-form-item label="排序开始值" prop="crudSort">
          <!--<el-input v-model.number="crudSort" type="number"/>-->
          <el-input-number
            v-model="crudSort"
            :step="1"
            :min="1"
            controls-position="right"
          />
        </el-form-item>
        <el-form-item label="功能按钮" prop="checkedCrudItems">
          <el-checkbox-group v-model="checkedCrudItems">
            <el-checkbox
              v-for="item in crudItems"
              :key="item.name"
              :label="item.name"
            >
              {{ item.name }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="crudFormVisible = false">取消</el-button>
        <el-button type="primary" @click="crudFormSave">确定</el-button>
      </div>
    </el-dialog>

    <el-dialog
      :visible.sync="batchFormVisible"
      :modal="false"
      :close-on-click-modal="false"
      title=""
      width="40%"
      class="mini-el-dialog"
    >
      <el-form
        ref="batchForm"
        :model="batchForm"
        label-position="left"
        class="resourceForm"
        label-width="100px"
      >
        <el-form-item label="排序开始值" prop="batchSort">
          <el-input-number
            v-model="batchSort"
            :step="1"
            :min="1"
            controls-position="right"
          />
        </el-form-item>
        <el-form-item label="功能按钮" prop="batchItems">
          <el-input
            v-for="(tag, index) in batchItems"
            :key="'tag_' + index"
            v-model="batchItems[index]"
            size="small"
            clearable
            @clear="batchItemRemove(index)"
          />
          <el-input
            v-if="batchItemInputVisible"
            ref="batchItemInput"
            v-model="batchItemInputValue"
            class="input-new-tag"
            size="small"
            placeholder="请输入名称"
            @keyup.enter.native="batchItemInputConfirm"
            @blur="batchItemInputConfirm"
          />
          <el-button
            v-else
            class="button-new-tag"
            size="small"
            @click="batchItemInputShow"
          >
            添加
          </el-button>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="batchFormVisible = false">取消</el-button>
        <el-button type="primary" @click="batchFormSave">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import PopoverConfirm from './components/PopoverConfirm'
import configure from './components/configure'
import resourceAPI from './api/resourceAPI'

export default {
  name: 'SysResource',
  components: { PopoverConfirm, configure },
  data () {
    return {
      domainList: [
        {
          value: '1',
          label: '一码游标准版'
        }
      ],
      listQuery: {
        domainId: import.meta.env.VITE_APP_domainId,
      },
      defaultProps: {
        children: 'children',
        label: 'title'
      },
      treeData: [],
      slaveTableData: [],
      expandedKeys: [],
      expandedKeyArr: [],
      actionType: '',
      cascaderOptions: [],
      cascaderProps: { value: 'id', label: 'title' },
      parentArr: [],
      postForm: {},
      dialogFormVisible: false,
      crudForm: {},
      crudFormVisible: false,
      checkedCrudItems: ['新增', '编辑', '删除', '查看', '启用/停用'],
      crudPrefixPath: '',
      crudItems: [
        { name: '新增', perm: '/create' },
        { name: '编辑', perm: '/update' },
        {
          name: '查看',
          perm: '/queryForDetail'
        },
        { name: '删除', perm: '/delete' },
        { name: '启用/停用', perm: '/updateStatus' }
      ],
      crudSort: 1,
      rules: {
        domainId: [
          { required: true, message: '系统域不能为空', trigger: 'blur' }
        ],
        name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
        type: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
        sort: [{ required: true, message: '排序值不能为空', trigger: 'blur' }],
        display: [
          { required: true, message: '显示状态值不能为空', trigger: 'blur' }
        ],
        status: [{ required: true, message: '状态值不能为空', trigger: 'blur' }]
      },
      dynamicTags: [],
      inputVisible: false,
      inputValue: '',
      batchItems: [],
      batchItemInputVisible: false,
      batchItemInputValue: '',
      batchFormVisible: false,
      batchForm: {},
      batchSort: 1
    }
  },
  created () {
    // 数组判断是否含有某个元素
    Array.prototype.contains = function (obj) {
      var i = this.length
      while (i--) {
        if (this[i] === obj) {
          return true
        }
      }
      return false
    }
    // 数组去重
    Array.prototype.uniquelize = function () {
      var ra = new Array()
      for (var i = 0; i < this.length; i++) {
        if (!ra.contains(this[i])) {
          ra.push(this[i])
        }
      }
      return ra
    }
    // 交集
    Array.prototype.jiaoji = function (obj) {
      return this.uniquelize().filter(function (o) {
        return obj.contains(o) ? o : null
      })
    }
    // 差集
    Array.prototype.minus = function (obj) {
      return this.uniquelize().filter(function (o) {
        return obj.contains(o) ? null : o
      })
    }
    // 并集
    Array.prototype.bingji = function (obj) {
      return this.concat(obj).uniquelize()
    }
    this.getTreeList()
  },
  methods: {
    handleFilter () {
      this.getTreeList()
    },
    // domainSelectChange () {
    //   const me = this
    //   if (me.$refs.tree) {
    //     me.$refs.tree.setCurrentKey(null)
    //   }
    //   me.getTreeList()
    // },
    getTreeList () {
      const me = this
      let currentNode = null
      if (me.$refs.tree) {
        currentNode = me.$refs.tree.getCurrentNode()
      }
      me.treeData = []
      me.cascaderOptions = []
      me.slaveTableData = []
      // this.listQuery
      resourceAPI.tree().then(response => {
        me.treeData = response.data
        me.cascaderOptions = response.data
        me.$set(me, 'expandedKeys', me.expandedKeyArr)
        if (currentNode != null) {
          me.$nextTick(function () {
            me.$refs.tree.setCurrentKey(currentNode.id)
          })
          this.getSlaveList(currentNode.id)
        } else {
          // if (me.treeData && me.treeData[0]) {
          //   me.$nextTick(function() {
          //     me.$refs.tree.setCurrentKey(me.treeData[0].id)
          //   })
          //   this.getSlaveList(me.treeData[0].id)
          // }
        }
      })
    },
    handleNodeClick (data) {
      this.getSlaveList(data.id)
    },
    handleNodeExpand (data, node, comp) {
      const me = this
      const arr = me.expandedKeyArr || []
      arr.push(node.data.id)
      me.expandedKeyArr = arr
    },
    handleNodeCollapse (data, node, comp) {
      const me = this
      const arr = me.getChildIDs(node)
      arr.push(node.data.id)
      const expandedKeyArr = me.expandedKeyArr || []
      me.expandedKeyArr = expandedKeyArr.minus(arr)
    },
    getChildIDs (node) {
      const ids = []
      const remap = function (ids, childNodes) {
        if (childNodes) {
          for (let i = 0; i < childNodes.length; i++) {
            if (childNodes[i].expanded) {
              ids.push(childNodes[i].data.id)
            }
            if (childNodes[i].childNodes) {
              remap(ids, childNodes[i].childNodes)
            }
          }
        }
      }
      remap(ids, node.childNodes)
      return ids
    },
    getSlaveList (parentId) {
      this.slaveTableData = []
      if (parentId) {
        resourceAPI.getSlaveList({ parentId: parentId }).then(response => {
          this.slaveTableData = response.data
        })
      }
    },
    parentSelectChange (value) {
      this.postForm.parentId = value[value.length - 1]
    },
    handleCreate () {
      this.dynamicTags = []
      this.actionType = 'add'
      const currentNode = this.$refs.tree.getCurrentNode()
      if (currentNode != null) {
        this.postForm = Object.assign(
          {},
          {
            domainId: this.listQuery.domainId,
            sort: 1,
            display: 1,
            status: 1,
            type: null,
            parentId: currentNode.id,
            configure: ''
          }
        )
        const parentObj = this.getParentObj(
          this.cascaderOptions,
          currentNode.id
        )
        this.parentArr = parentObj.parentIdPath
      } else {
        this.postForm = Object.assign(
          {},
          {
            domainId: this.listQuery.domainId,
            sort: 1,
            display: 1,
            status: 1,
            type: null,
            configure: ''
          }
        )
        this.parentArr = []
      }
      this.dialogFormVisible = true
    },
    handleEdit (data) {
      this.dynamicTags = []
      this.actionType = 'edit'
      this.postForm = Object.assign({}, {})
      const id = data.id
      resourceAPI.detail({ id }).then(
        response => {
          this.postForm = response.data
          this.dynamicTags = response.data.perm
            ? response.data.perm.split(';')
            : []
          const parentObj = this.getParentObj(
            this.cascaderOptions,
            this.postForm.parentId
          )
          this.parentArr = parentObj.parentIdPath
          this.dialogFormVisible = true
        },
        err => {
          console.log(err)
        }
      )
    },
    handleDelete (data) {
      const id = data.id
      resourceAPI.delete({ id }).then(
        res => {
          this.$notify({
            title: '成功',
            message: '删除成功',
            type: 'success',
            duration: 2000
          })
          this.$refs.tree.setCurrentKey(null)
          this.getTreeList()
        },
        err => {
          this.$notify({
            title: '失败',
            message: '删除失败',
            type: 'error',
            duration: 2000
          })
        }
      )
    },
    slaveHandleCreate () {
      const currentNode = this.$refs.tree.getCurrentNode()
      if (currentNode != null && !currentNode.children) {
        this.dynamicTags = []
        this.actionType = 'slaveAdd'
        this.postForm = Object.assign(
          {},
          {
            domainId: this.listQuery.domainId,
            sort: 1,
            display: 1,
            status: 1,
            type: '2',
            parentId: currentNode.id
          }
        )
        const parentObj = this.getParentObj(
          this.cascaderOptions,
          currentNode.id
        )
        this.parentArr = parentObj.parentIdPath
        this.dialogFormVisible = true
      } else {
        this.$swal.warning('请选择左侧叶子节点')
      }
    },
    slaveHandleCrud () {
      const me = this
      const currentNode = me.$refs.tree.getCurrentNode()
      if (currentNode != null && !currentNode.children) {
        me.crudPrefixPath = ''
        me.crudSort = 1
        me.crudFormVisible = true
      } else {
        me.$swal.warning('请选择左侧叶子节点')
      }
    },
    crudFormSave () {
      const me = this
      const currentNode = me.$refs.tree.getCurrentNode()
      if (me.checkedCrudItems && me.checkedCrudItems.length > 0) {
        const postDataArr = []
        const selectArr = me.crudItems.filter(item =>
          me.checkedCrudItems.includes(item.name)
        )

        for (let i = 0; i < selectArr.length; i++) {
          postDataArr.push({
            parentId: currentNode.id,
            domainId: me.listQuery.domainId,
            name: selectArr[i].name,
            type: '2',
            sort: me.crudSort + i,
            perm: me.crudPrefixPath
              ? me.crudPrefixPath + selectArr[i].perm
              : '',
            display: 1,
            status: 1
          })
        }

        me.slaveTableData = me.slaveTableData || []

        let num = 0
        for (let i = 0; i < postDataArr.length; i++) {
          resourceAPI.create(postDataArr[i]).then(
            res => {
              me.slaveTableData.push(res.data)
              num++
              if (num == postDataArr.length) {
                me.crudFormVisible = false
                me.getSlaveList(currentNode.id)
              }
            },
            err => {
              console.log(err)
            }
          )
        }
      }
    },

    batchHandle () {
      const me = this
      const currentNode = me.$refs.tree.getCurrentNode()
      if (currentNode != null && !currentNode.children) {
        me.batchItems = []
        me.batchFormVisible = true
      } else {
        me.$swal.warning('请选择左侧叶子节点')
      }
    },
    batchFormSave () {
      const me = this
      const currentNode = me.$refs.tree.getCurrentNode()
      if (me.batchItems && me.batchItems.length > 0) {
        const postDataArr = []
        const selectArr = me.batchItems
        for (let i = 0; i < selectArr.length; i++) {
          postDataArr.push({
            parentId: currentNode.id,
            domainId: me.listQuery.domainId,
            name: selectArr[i],
            type: '2',
            sort: me.batchSort + i,
            perm: '',
            display: 1,
            status: 1
          })
        }
        me.slaveTableData = me.slaveTableData || []

        let num = 0
        for (let i = 0; i < postDataArr.length; i++) {
          resourceAPI.create(postDataArr[i]).then(
            res => {
              me.slaveTableData.push(res.data)
              num++
              if (num == postDataArr.length) {
                me.batchFormVisible = false
                me.getSlaveList(currentNode.id)
              }
            },
            err => {
              console.log(err)
            }
          )
        }
      }
    },

    slaveHandleEdit (row) {
      this.dynamicTags = []
      this.actionType = 'slaveEdit'
      this.postForm = Object.assign({}, {})
      const id = row.resourceId
      resourceAPI.detail({ id }).then(
        response => {
          this.postForm = response.data
          this.dynamicTags = response.data.perm
            ? response.data.perm.split(';')
            : []
          const parentObj = this.getParentObj(
            this.cascaderOptions,
            this.postForm.parentId
          )
          this.parentArr = parentObj.parentIdPath
          this.dialogFormVisible = true
        },
        err => {
          console.log(err)
        }
      )
    },
    slaveHandleDelete (row) {
      const id = row.resourceId
      resourceAPI.delete({ id }).then(
        res => {
          this.$notify({
            title: '成功',
            message: '删除成功',
            type: 'success',
            duration: 2000
          })
          this.getTreeList()
        },
        err => {
          this.$notify({
            title: '失败',
            message: '删除失败',
            type: 'error',
            duration: 2000
          })
          console.log(err)
        }
      )
    },
    submitForm () {
      this.$refs.form.validate(valid => {
        if (valid) {
          const postData = Object.assign({}, this.postForm)
          postData.parentId = postData.parentId || postData.domainId

          postData.perm = this.dynamicTags && this.dynamicTags.join(';')

          if (postData.resourceId) {
            resourceAPI.update(postData).then(
              res => {
                this.$notify({
                  title: '成功',
                  message: '修改成功',
                  type: 'success',
                  duration: 2000
                })
                this.dialogFormVisible = false
                this.getTreeList()
              },
              err => {
                this.$notify({
                  title: '失败',
                  message: '修改失败',
                  type: 'error',
                  duration: 2000
                })
                console.log(err)
              }
            )
          } else {
            resourceAPI.create(postData).then(
              res => {
                this.$notify({
                  title: '成功',
                  message: '创建成功',
                  type: 'success',
                  duration: 2000
                })
                this.dialogFormVisible = false
                this.getTreeList()
              },
              err => {
                this.$notify({
                  title: '失败',
                  message: '创建失败',
                  type: 'error',
                  duration: 2000
                })
                console.log(err)
              }
            )
          }
        }
      })
    },

    removeTag (index) {
      this.dynamicTags.splice(index, 1)
    },
    tagClickHandle (tag) {},
    showInput () {
      this.inputVisible = true
      this.$nextTick(_ => {
        this.$refs.saveTagInput.$refs.input.focus()
      })
    },
    handleInputConfirm () {
      const inputValue = this.inputValue
      if (inputValue) {
        this.dynamicTags.push(inputValue)
      }
      this.inputVisible = false
      this.inputValue = ''
    },

    batchItemRemove (index) {
      this.batchItems.splice(index, 1)
    },
    batchItemInputShow () {
      this.batchItemInputVisible = true
      this.$nextTick(_ => {
        this.$refs.batchItemInput.$refs.input.focus()
      })
    },
    batchItemInputConfirm () {
      const batchItemInputValue = this.batchItemInputValue
      if (batchItemInputValue) {
        this.batchItems.push(batchItemInputValue)
        this.batchItemInputVisible = true
      } else {
        this.batchItemInputVisible = false
      }
      this.batchItemInputValue = ''
    },

    getParentObj (treeData, parentId) {
      const ids = []
      const names = []
      const remap = function (arr, id) {
        for (let i = 0; i < arr.length; i++) {
          if (arr[i].id === id) {
            ids.push(arr[i].id)
            names.push(arr[i].title)
            remap(treeData, arr[i].parentId)
          } else if (arr[i].children) {
            remap(arr[i].children, id)
          }
        }
      }
      remap(treeData, parentId)
      const newIds = ids.reverse()
      const newNames = names.reverse()
      return {
        parentId: newIds.length >= 1 ? newIds[newIds.length - 1] : null,
        parentName: newNames.length >= 1 ? newNames[newNames.length - 1] : null,
        parentIdPath: newIds,
        parentNamePath: newNames
      }
    }
  },
  filters: {
    typeAnalysis (type) {
      let types = ['目录', '菜单', '按钮']
      return types[type] || ''
    }
  }
}
</script>
<style lang="scss">
.menu-tree {
  .el-tree-node__content {
    height: auto;
    .el-tree-node__expand-icon {
      font-size: 16px;
    }
    .is-leaf {
      font-size: 0;
    }
    .custom-tree-node {
      font-size: 14px;
      line-height: 45px;
      border-bottom: 1px solid #ebeef5;
    }
  }
}
</style>
<style scoped lang="scss">
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 12px;
}

.resourceForm .el-tag {
  position: relative;
  display: block;
  margin-top: 5px;
}

.resourceForm .el-tag .el-icon-close {
  position: absolute;
  top: 6px;
  right: 3px;
}
:deep(.el-table__cell) {
  .el-button {
    margin-right: 6px;
    &:last-child {
      margin-right: 0;
    }
  }
}
:deep(.mini-el-dialog) {
  background: rgba(0, 0, 0, 0.5);
  .el-dialog {
    margin-top: 3vh !important;
    margin-bottom: 0 !important;
  }
}
</style>
